Many enterprise-class storage arrays available today incorporate two disk array controllers (referred to as “controllers”). This dual controller configuration enables high availability—if one controller fails, the other controller can take over and thereby ensure that the storage array is able to continue servicing I/O requests.
Storage vendors generally offer three different types of dual controller storage arrays: (1) “Active/Active,” (2) “Active/Standby,” and (3) Asymmetric Logical Unit Access (ALUA). In an Active/Active storage array, both controllers are active at all times and can service I/O requests directed to any logical disk (e.g., LUN) resident on the storage array, without any difference in performance. In an Active/Standby storage array, only one controller (i.e., the primary controller) is active at any given time; the other controller (i.e., the secondary controller) is in standby mode. Thus, a host system accessing an Active/Standby storage array can only send I/O requests to the primary controller. An ALUA storage array is similar to an Active/Active storage array in that both controllers are active at all times. However, for any given logical disk resident on an ALUA storage array, only one of the two controllers is optimized. As a result, I/O performance via the unoptimized controller is worse than the optimized controller.
A host system that communicates with a dual controller storage array typically has multiple host bus adapters (HBAs) that connect to the storage array's two controllers. This means that the host system has multiple paths to the storage array (one path per HBA-controller connection). Existing server operating systems and virtualization platforms take advantage of these multiple paths (beyond the high availability use case) by load balancing I/O requests across the paths to achieve better I/O performance (referred to as “multipath load balancing”). However, current multipath load balancing implementations have certain limitations when used in conjunction with ALUA storage arrays. For example, in current implementations, a host system will generally load balance I/O requests only across the optimized paths between the host system and an ALUA storage array (i.e., the paths leading to the optimized controller); the host system will not transmit any I/O requests along an unoptimized path, barring a failure of the optimized controller.
The foregoing approach of utilizing only optimized paths for load balancing purposes works relatively well for hard disk-based ALUA storage arrays, since hard disk-based arrays have relatively high I/O latency and can support relatively few I/O Operations Per Second (IOPS) (e.g., 100K or less), and therefore I/O contention in this scenario generally occurs on the array, rather than the host side (in other words, the optimized paths between the host system and the storage array are rarely saturated). However, this approach is less suitable for “all-flash” ALUA storage arrays (i.e., ALUA storage arrays based entirely on flash storage) that are becoming increasingly popular. An all-flash ALUA storage array can easily serve millions of IOPS and thus can saturate the optimized paths leading from a host system. This shifts the point of I/O contention from the array side to the host side and significantly increases the amount of host-to-array I/O bandwidth needed to keep the storage array fully utilized, typically beyond what the optimized paths alone can deliver.